#ifndef __ADVENTURE_OBJECT_MEMORY_CACHE_H__
#define __ADVENTURE_OBJECT_MEMORY_CACHE_H__

/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 adventure_map.h

	$Header: /heroes4/adventure_object_memory_cache.h $

	$NoKeywords: $

 ************************************************************************/

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <map>
#include <streambuf>

//#include "adventure_map.h"
#include "adventure_object_global_id.h"
#include "counted_ptr.h"
#include "memory_buffer.h"

class t_adventure_map;
class t_adventure_object;
class t_adventure_object_cache_manager;

typedef t_counted_ptr<t_adventure_map>												t_adventure_map_ptr;
typedef t_counted_ptr<t_adventure_object_cache_manager>								t_adventure_object_cache_manager_ptr;

/////////////////////////////////////////////////////////////////
//the memory cache stores a 

class  t_adventure_object_memory_cache : public t_counted_object
{
public:
	t_adventure_object_memory_cache();
	virtual ~ t_adventure_object_memory_cache();

	bool	update_state( t_adventure_object * object );

	int		increment();
	int		decrement();

	virtual bool	read( std::streambuf & buffer );
	virtual bool	write( std::streambuf & buffer );


	t_memory_buffer_counted_ptr const & get_data_buffer();

protected:
		
	t_memory_buffer_counted_ptr		m_data_buffer;
	bool							m_is_town;
	int								m_memory_cache_refrence;
};

typedef t_counted_ptr<t_adventure_object_memory_cache>	t_adventure_object_memory_cache_ptr;

/////////////////////////////////////////////////////////////////
//the refrence_object is part of the adventure class it increments or decrements
//based upon the existance of an adventure object.

class t_adventure_object_memory_cache_refrence
{
public:
	t_adventure_object_memory_cache_refrence();
	virtual ~t_adventure_object_memory_cache_refrence();

	void	set_adventure_manager_for_memory_cache( t_adventure_map * map );
	void	set_cache_for_memory_cache( t_adventure_object_memory_cache * cache );
	void	set_global_id_for_memory_cache( t_adventure_global_id	object_gid );

protected:
	
	t_adventure_object_memory_cache_ptr						m_cache;
	t_adventure_object_cache_manager_ptr					m_manager;
	t_adventure_global_id									m_object_gid;

};

typedef t_counted_ptr<t_adventure_object_memory_cache>								t_adventure_object_memory_cache_ptr;
typedef std::map<t_adventure_global_id, t_adventure_object_memory_cache_ptr>		t_adventure_state_event_cache_map;

/////////////////////////////////////////////////////////////////
//the memory cache manager 

class  t_adventure_object_cache_manager : public t_counted_object
{
public:
	t_adventure_object_cache_manager();
	virtual ~t_adventure_object_cache_manager();

	bool										attach_adv_objects_to_their_cache( t_adventure_map* map );
	t_adventure_object_memory_cache *			get_memory_cache( t_adventure_object * object );

	bool		is_empty( t_adventure_global_id const & global_id );

	void		insert( t_adventure_object * object );
	void		remove( t_adventure_object * object );
	void		remove( t_adventure_global_id global_id );
	void		update( t_adventure_object * object );

	virtual bool	read( std::streambuf & buffer );
	virtual bool	write( std::streambuf & buffer );

protected:

	t_adventure_state_event_cache_map	m_replay_event_state_map;

};

#endif //__ADVENTURE_OBJECT_MEMORY_CACHE_H__